<script setup>
  import { useNavbarHeight } from '@/composables/useNavbarHeight'
  import { useTopDistance } from '@/composables/useTopDistance'
  import { useLocationStore } from '@/stores'
  import { DIAMOND_POSITION_LIST, FILTER_LIST, FILTER_MAP, OSS_BASE_URL } from '@/contants/home'
  import { computed, ref, watch } from 'vue'
  import filterByArea from './components/filter/filter-by-area.vue'
  import filterByPrice from './components/filter/filter-by-price.vue'
  import filterByType from './components/filter/filter-by-type.vue'
  import filterBySort from './components/filter/filter-by-sort.vue'
  import { getFilterPullListApi, getHouseListApi } from '@/api/home'
  import { normalize } from '@/utils/normalize'
  import { getLongitudeAndLatitude } from '@/utils/getLocation'
  import { onLoad } from '@dcloudio/uni-app'

  const locationStore = useLocationStore()

  const opsType = ref('')

  // 是否吸顶
  const isFixedTop = ref(false)
  // 自定义导航条高度
  const { NAV_BAR_HEIGHT } = useNavbarHeight()

  const { TOP_DISTANCE } = useTopDistance('.index-filter')

  // scroll-view 滚动事件
  const onScroll = (e) => {
    // 判断是否需要吸顶
    isFixedTop.value = e.detail.scrollTop >= TOP_DISTANCE.value
    if (!isFixedTop.value) {
      scrollIntoView.value = null
    }
  }

  // 弹出层 top 定位值
  const popupTop = computed(() => {
    return NAV_BAR_HEIGHT.value + uni.upx2px(88)
  })

  const scrollIntoView = ref(null)

  const visible = ref(false)

  // 打开弹出层
  const onOpen = (item) => {
    getFilterPullList()
    FILTER_LIST.value.forEach((item) => {
      item.isOpen = false
    })
    opsType.value = item.key
    item.isOpen = !item.isOpen
    if (!isFixedTop.value) {
      // 吸顶
      scrollIntoView.value = 'index-filter'
    }
    isFixedTop.value = true
    // 打开弹出层
    visible.value = true
  }
  // 弹出层关闭时
  const onPopupClose = () => {
    FILTER_LIST.value.forEach((item) => {
      if (item.isOpen) {
        item.isOpen = false
      }
    })
    // 回归原位
    isFixedTop.value = false
  }
  const onLeftClick = () => {
    uni.navigateTo({
      url: '/pages/index/city-select'
    })
  }

  // 跳转至筛选列表页
  const gotoFilterListPage = (key) => {
    uni.navigateTo({
      url: `/pages/index/filter-list?rentType=${key}`
    })
  }

  // 区域列表
  const regionList = ref([])
  // 租金列表
  const rentRangeList = ref([])
  // 户型列表
  // 1.出租方式
  const rentTypeList = ref([])
  // 2.房屋数量
  const roomNumList = ref([])

  // 是否切换了城市
  let isSwitchCityOrRegion = true

  // 获取下拉筛选列表
  async function getFilterPullList() {
    if (!isSwitchCityOrRegion) return
    isSwitchCityOrRegion = false
    const resp = await getFilterPullListApi({
      cityId: locationStore.location.id,
      dirtTypes: ['rent_range', 'rent_type_list', 'room_num']
    })
    regionList.value = normalize(resp.regionList)
    rentRangeList.value = normalize(resp.dictMap.rent_range)
    rentTypeList.value = normalize(resp.dictMap.rent_type_list)
    roomNumList.value = normalize(resp.dictMap.room_num)
  }

  const areaRef = ref(null)
  const priceRef = ref(null)
  const houseTypeRef = ref(null)
  // 记录选择的地区(id和name)
  const selectedRegion = ref({})
  // 选择的租金列表
  const selectedRentPriceList = ref([])
  // 选择出租类型列表
  const selectedRentTypeList = ref([])
  // 选择的房间数量列表
  const selectedRoomNumList = ref([])
  // 选择的排序规则
  const selectedSort = ref({})
  // 分页参数
  const pageQuery = {
    pageNo: 1, // 页码
    pageSize: 10 // 条数
  }

  // 房源列表
  const houseList = ref([])
  // 是否在请求中
  const isLoading = ref(true)
  // 是否加载结束
  let isFinished = false

  // 点击确定按钮
  const onConfirm = async (e) => {
    isLoading.value = true
    pageQuery.pageNo = 1
    houseList.value = []
    isFinished = false
    // 根据操作类型，获取当前选中的值
    switch (opsType.value) {
      case FILTER_MAP.AREA:
        const { currentIndex } = areaRef.value
        selectedRegion.value = regionList.value[currentIndex]
        break
      case FILTER_MAP.RENT_PRICE:
        const { selectedPriceList } = priceRef.value
        selectedRentPriceList.value = selectedPriceList
        break
      case FILTER_MAP.HOUSE_TYPE:
        const { selectedRentList, selectedRoomList } = houseTypeRef.value
        selectedRentTypeList.value = selectedRentList
        selectedRoomNumList.value = selectedRoomList
        break
      case FILTER_MAP.SORT:
        selectedSort.value = e
        break
    }
    isFixedTop.value = false
    visible.value = false
    FILTER_LIST.value.forEach((item) => {
      if (item.isOpen) {
        item.isOpen = false
      }
    })
    getHouseList()
  }
  // 城市信息
  const cityInfo = computed(() => {
    return locationStore.location
  })
  // 监视城市信息
  watch(cityInfo, (newVal) => {
    // 如果有了城市 id，发起初始化请求
    if (newVal.id) {
      getHouseList()
    }
  })

  // 获取房源列表
  async function getHouseList() {
    isLoading.value = true
    // 处理选中的值，符合接口格式
    const cityId = locationStore.location.id
    const regionId = selectedRegion.value.id || null
    const rentalRanges = selectedRentPriceList.value.filter((item) => item.key !== null).length
      ? selectedRentPriceList.value.map((item) => item.key)
      : null
    const rentTypes = selectedRentTypeList.value.filter((item) => item.key !== null).length
      ? selectedRentTypeList.value.map((item) => item.key)
      : null
    const rooms = selectedRoomNumList.value.filter((item) => item.key !== null).length
      ? selectedRoomNumList.value.map((item) => item.key)
      : null
    const sort = selectedSort.value.key || 'distance'
    let latitude = null
    let longitude = null
    if (!locationStore.location.latitude || !locationStore.location.longitude) {
      const resp = await getLongitudeAndLatitude()
      latitude = resp.latitude
      longitude = resp.longitude
    } else {
      latitude = locationStore.location.latitude
      longitude = locationStore.location.longitude
    }
    // 调用接口，请求房源列表
    const { list, totalPages } = await getHouseListApi({
      cityId,
      regionId,
      rentalRanges,
      rentTypes,
      rooms,
      sort,
      longitude,
      latitude,
      ...pageQuery
    })
    // 没有数据了
    if (pageQuery.pageNo > totalPages || list.length <= 0) {
      isFinished = true
      uni.showToast({
        title: '没有更多数据了',
        icon: 'none'
      })
    } else {
      // 合并房源列表
      houseList.value = [
        ...houseList.value,
        ...list.map((item) => ({
          ...item,
          headImage: OSS_BASE_URL + item.headImage
        }))
      ]
    }
    // 加载结束
    isLoading.value = false
  }

  // 触底
  const onReachBottom = () => {
    if (isLoading.value) return
    if (isFinished)
      return uni.showToast({
        title: '没有更多数据了',
        icon: 'none'
      })
    pageQuery.pageNo++
    getHouseList()
  }
  // 区域是否选择了
  const isRegionActive = computed(() => {
    return Object.keys(selectedRegion.value).length > 0 && selectedRegion.value.id !== 0
  })

  // 租金是否选择了
  const isRentPriceActive = computed(() => {
    return selectedRentPriceList.value.filter((item) => item.id !== 0).length > 0
  })

  // 户型是否选择了
  const isHouseTypeActive = computed(() => {
    return (
      selectedRentTypeList.value.filter((item) => item.id !== 0).length > 0 ||
      selectedRoomNumList.value.filter((item) => item.id !== 0).length > 0
    )
  })
  // 排序是否选择了
  const isSortActive = computed(() => {
    return !!Object.keys(selectedSort.value).length && selectedSort.value.key !== 'distance'
  })

  onLoad(() => {
    uni.$on('cityChange', () => {
      isSwitchCityOrRegion = true
      houseList.value = []
      pageQuery.pageNo = 1
      isLoading.value = true
      isFinished = false
    })
  })

  // 选择了排序规则关闭弹出层
  const onClose = () => {
    visible.value = false
    FILTER_LIST.value.forEach((item) => {
      if (item.isOpen) {
        item.isOpen = false
      }
    })
  }

  const defaultImage = 'https://bitejiaoyan.oss-cn-chengdu.aliyuncs.com/bitehouse/web/home/default.png'
  const onError = (i) => {
    houseList.value[i].headImage = defaultImage
  }
</script>

<template>
  <!-- 头部导航栏 -->
  <bit-nav-bar
    title="比特租房"
    @leftClick="onLeftClick"
  >
    <template #left>
      <text class="city">{{ locationStore.location.fullName || '北京市' }}</text>
      <bit-icon
        color="#333"
        size="26"
        >&#xe6e9;</bit-icon
      >
    </template>
  </bit-nav-bar>
  <scroll-view
    class="index"
    :scroll-into-view="scrollIntoView"
    :scroll-with-animation="true"
    scroll-y
    @scroll="onScroll"
    @scrolltolower="onReachBottom"
  >
    <!-- banner区域 -->
    <view class="index-banner">
      <image
        class="index-banner-image"
        src="https://bitejiaoyan.oss-cn-chengdu.aliyuncs.com/bitehouse/web/home/banner.png"
      />
    </view>
    <!-- 金刚位 -->
    <view class="index-diamond">
      <view
        class="index-diamond-item"
        v-for="item in DIAMOND_POSITION_LIST"
        :key="item.id"
        @click="gotoFilterListPage(item.key)"
      >
        <image
          class="index-diamond-item-image"
          :src="item.iconPath"
        />
        <text class="index-diamond-item-text">{{ item.name }}</text>
      </view>
    </view>
    <!-- 筛选条件 -->
    <view
      id="index-filter"
      class="index-filter"
      :style="{ top: isFixedTop ? `${NAV_BAR_HEIGHT}px` : 0 }"
      :class="{ fixedTop: isFixedTop }"
    >
      <view
        class="index-filter-item"
        v-for="item in FILTER_LIST"
        :key="item.id"
        @click="onOpen(item)"
      >
        <template>
          <text
            v-if="item.key === FILTER_MAP.AREA"
            class="index-filter-item-text"
            :class="{ active: item.isOpen || isRegionActive }"
            >{{ selectedRegion.name || item.name }}
          </text>
          <text
            class="index-filter-item-text"
            :class="{ active: item.isOpen || isRentPriceActive }"
            v-else-if="item.key === FILTER_MAP.RENT_PRICE"
            >{{ item.name }}</text
          >
          <text
            class="index-filter-item-text"
            :class="{ active: item.isOpen || isHouseTypeActive }"
            v-else-if="item.key === FILTER_MAP.HOUSE_TYPE"
            >{{ item.name }}</text
          >
          <text
            class="index-filter-item-text"
            :class="{ active: item.isOpen || isSortActive }"
            v-else
            >{{ item.name }}</text
          >
        </template>

        <bit-icon
          v-if="item.isOpen"
          color="#0FA1FE"
          size="26"
          >&#xe6e8;</bit-icon
        >
        <bit-icon
          v-else
          color="#999"
          size="26"
          >&#xe6e9;</bit-icon
        >
      </view>
    </view>
    <!-- 房源列表 -->
    <view
      class="index-house-list"
      v-if="houseList.length"
    >
      <bit-house-item
        v-for="(item, index) in houseList"
        :key="item.houseId"
        :item="item"
        :index="index"
        @error="onError"
      />
    </view>
    <!-- 缺省图 -->
    <view
      class="index-no-content"
      v-else-if="!isLoading"
    >
      <image
        src="https://bitejiaoyan.oss-cn-chengdu.aliyuncs.com/bitehouse/web/common/quesheng.png"
        mode="scaleToFill"
        class="index-no-content__image"
      />
      <text class="index-no-content__text">暂无内容</text>
    </view>
  </scroll-view>

  <!-- 弹出层 -->
  <bit-popup
    v-model="visible"
    :top="popupTop"
    @close="onPopupClose"
    @confirm="onConfirm"
    :showConfirmButton="opsType !== FILTER_MAP.SORT"
  >
    <filterByArea
      v-if="opsType === FILTER_MAP.AREA"
      ref="areaRef"
      :regionList="regionList"
    />
    <filterByPrice
      ref="priceRef"
      v-else-if="opsType === FILTER_MAP.RENT_PRICE"
      :rentRangeList="rentRangeList"
    />
    <filterByType
      ref="houseTypeRef"
      v-else-if="opsType === FILTER_MAP.HOUSE_TYPE"
      :rentTypeList="rentTypeList"
      :roomNumList="roomNumList"
    />
    <filterBySort
      v-else-if="opsType === FILTER_MAP.SORT"
      @close="onClose"
      @change="onConfirm"
    />
  </bit-popup>
</template>

<style lang="scss" scoped>
  @import '@/styles/variable.scss';
  @import '@/styles/mixins.scss';
  .index {
    position: fixed;
    left: 0;
    right: 0;
    top: 176rpx;
    bottom: 0;
    z-index: -1;
    box-sizing: border-box;
    padding: 0 30rpx;
    background-color: var(--main-bg-color);
    &-banner {
      box-sizing: border-box;
      height: 222rpx;
      margin-top: 30rpx;
      &-image {
        width: 100%;
        height: 100%;
      }
    }
    // 金刚位
    &-diamond {
      display: flex;
      justify-content: space-evenly;
      align-items: center;
      padding: 30rpx 0;
      &-item {
        flex: 1;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        &-image {
          width: 92rpx;
          height: 92rpx;
          border-radius: 38rpx;
        }
        &-text {
          margin-top: 10rpx;
          font-size: var(--font-size-xs);
          color: var(--text-color-dark);
        }
      }
    }
    // 筛选条件
    &-filter {
      box-sizing: border-box;
      display: flex;
      justify-content: space-between;
      align-items: center;
      height: 88rpx;
      padding: 0 50rpx;
      background: #fff;
      border-radius: 20rpx;
      &-item {
        font-size: var(--font-size-sm);

        &-text {
          width: 60rpx;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          &.active {
            color: var(--text-active-color);
          }
        }
      }
      &.fixedTop {
        position: fixed;
        left: 0;
        right: 0;
        width: 100vw;
        z-index: 99999;
      }
    }
    &-house-list {
      margin-top: 20rpx;
    }
    &-no-content {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      width: 588rpx;
      height: 541rpx;
      margin: 85rpx 51rpx 0;
      padding-bottom: 47rpx;

      &__image {
        width: 100%;
      }
      &__text {
        font-size: var(--font-size-sm);
        color: var(--text-color-light);
      }
    }
  }
</style>
